#include "MarsPrecompile.h"

#include "MarsCamera.h"

using namespace Core;
using namespace GObject;

//////////////////////////////////////////////////////////////////////////
typedef struct _MemoryNode
{
	Core::ptr							StartAddr;
	Core::ptr							ObjAddr;
	Core::uint32						Size;
	Core::uint32						Align;
} MemoryNode;

typedef std::map< Core::ptr, MemoryNode >	MemoryNodeMap;
typedef MemoryNodeMap::iterator				MemoryNodeMapItr;
typedef MemoryNodeMap::const_iterator		MemoryNodeMapConstItr;

static MemoryNodeMap s_mapMemoryNodes;

//////////////////////////////////////////////////////////////////////////
void* Camera::operator new ( Core::uint32 size )
{
	MemoryNode node;
	node.StartAddr = ( Core::ptr ) malloc( size + 15 );
	node.ObjAddr = ( ( ( Core::ptr ) node.StartAddr + 15 ) & ~( 15 ) );
	node.Size = size;
	node.Align = 16;

	s_mapMemoryNodes.insert( std::make_pair( node.ObjAddr, node ) );
	return ( void* ) node.ObjAddr; 
}

void Camera::operator delete ( void* p )
{	
	MemoryNodeMapItr it = s_mapMemoryNodes.find( ( Core::ptr ) p );
	if ( it != s_mapMemoryNodes.end() )
	{
		free( ( void * ) it->second.StartAddr );
		s_mapMemoryNodes.erase( it );
	}
	else
	{
		MARS_ASSERT( "Can't find the pointer in the memory node map." );
	}
}

//////////////////////////////////////////////////////////////////////////
Camera::Camera( ProjectType type )
	: m_eType( type )
	, m_pos( 0.0f, 0.0f, 0.0f )
	, m_target( 0.0f, 0.0f, 1.0f )
	, m_up( 0.0f, 1.0f, 0.0f )
	, m_fFov( XM_PIDIV4 )
	, m_fRatio( 4.0f / 3.0f )
	, m_fNearClip( 0.01f )
	, m_fFarClip( 100.0f )
	, m_bDirtyViewMatrix( true )
	, m_bDirtyProjMatrix( true )
{
	UpdateViewMatrix();
	UpdateProjMatrix();
}

void Camera::UpdateViewMatrix() const
{
	m_viewMatrix = XMMatrixLookAtLH( XMLoadFloat3( &m_pos ), XMLoadFloat3( &m_target ), XMLoadFloat3( &m_up ) );
	m_bDirtyViewMatrix = false;
}

void Camera::UpdateProjMatrix() const
{
	m_projMatrix = XMMatrixPerspectiveFovLH( m_fFov, m_fRatio, m_fNearClip, m_fFarClip );
	m_bDirtyProjMatrix = false;
}
